#include<iostream>
#include<unistd.h>
#include<pthread.h>
#include<vector>
#include<cstdlib>
#include<semaphore.h>

#define NUM 5
using namespace std;


template<class T>
class RingQueue
{
  private:
    vector<T>q;
    int cap;
    int c_pos;
    int p_pos;

    //信号量
    sem_t Blank_sem;
    sem_t Data_sem;
  private:
    void P(sem_t &s)
    {
      sem_wait(&s);
    }
    void V(sem_t &s)
    {
      sem_post(&s);
    }
  public:
    //构造
    RingQueue(int cap=NUM)
      :cap(NUM)
      ,c_pos(0)
      ,p_pos(0)
      {
        q.resize(cap);
        sem_init(&Blank_sem,0,NUM);
        sem_init(&Data_sem,0,0);
      }
    //生产者调用，关心空间大小
    void push(const T&data)
    {
      //P操作让信号量的计数器--,使的空间信号量减少
      P(Blank_sem);
      q[p_pos]=data;
      //V操作让信号量的计数器++,使的数据信号量增加
      V(Data_sem);
      p_pos++;
      p_pos%=cap;
      usleep(1000);
    }
    void pop(T&data)
    {
      P(Data_sem);
      data=q[c_pos];
      V(Blank_sem);
      c_pos++;
      c_pos%=cap;
    }
    ~RingQueue()
    {
      sem_destroy(&Blank_sem);
      sem_destroy(&Data_sem);
    }

};
